<?php
namespace Common\Service;
use Think\Model;
use Think\Log;
use Think\Think;

class CicService{
    public $error;
    public $response_data;
    
    /**
    * 调用中华保险远程接口
    * 
    * @param mixed $xml 报文内容
    * @return mixed 返回xml格式的内容
    */
    protected function callRemote($xml){
        try{
            Log::record($xml,Log::DEBUG);
            $client = new \SoapClient(C('CIC_URL'));
            $param = array('content' => $xml);
            $data = $client->getRequest($param);
            Log::record($data->return,Log::DEBUG);
        }catch(Execption $e){
            return false;            
        }
        return $data->return;        
    }
    
    /**
    * 将XML转换成数组
    *         
    * @param \SimpleXmlIterator $xml
    * @param mixed $nameSpaces
    */
    protected function xmlNameSpaceToArray(\SimpleXmlIterator $xml, $nameSpaces=Null){
          $preparedArray = array();
          for($xml->rewind(); $xml->valid(); $xml->next()) {
                $key = $xml->key();
                if(!isset($preparedArray[$key])) {
                    $preparedArray[$key] = array(); 
                    $i=0; 
                }else{
                    $i = count($preparedArray[$key]);
                }
                $simple = true;
                foreach($xml->current()->attributes() as $k=>$v) {
                    $preparedArray[$key][$i][$k]=(string)$v;
                    $simple = false;
                }
                if($nameSpaces) {
                    foreach($nameSpaces as $nid=>$name) {
                        foreach($xml->current()->attributes($name) as $k=>$v) {
                            $preparedArray[$key][$i][$nid.':'.$k]=(string)$v;
                            $simple = false;
                        }
                    }
                } 
                if($xml->hasChildren()) {
                    if($simple){
                        $preparedArray[$key][$i] = $this->xmlNameSpaceToArray($xml->current(), $nameSpaces);
                    }else{
                        $preparedArray[$key][$i]['content'] = $this->xmlNameSpaceToArray($xml->current(), $nameSpaces);
                    }
                } else {
                    if($simple){
                        $preparedArray[$key][$i] = strval($xml->current());
                    }else{
                        $preparedArray[$key][$i]['content'] = strval($xml->current());
                    }
                }
                $i++;
          }
          foreach($preparedArray as $key => &$value){
              if(is_array($value) && count($value)==1 && isset($value[0])){
                  $value = $value[0];
              }
          }
          return $preparedArray;
    }
    
    /**
    * 生成用于远程请求的
    * 
    * @param mixed $template 模板文件
    * @param mixed $params 参数数组
    */
    protected function generatorXml($template,$params){
        $view = Think::instance('Think\View');
        $view->assign('user_name',C('CIC_ECUSER'));
        $view->assign('user_psw',C('CIC_ECPASS'));
        $view->assign('channelcode',C('CIC_CHANNELCODE'));
        foreach($params as $key => $value){
            $view->assign($key,$value);
        }
        return $view->fetch("Common@Cic:$template");
    }
    
    /**
    * 产生一次请求，并返回信息
    * 
    * @param mixed $template  请求模板文件
    * @param mixed $params 请求参数
    * @param boolean $needMain 是否需要保留MAIN部分
    * @return mixed 成功返回包含内容的数组，失败返回false
    */
    protected function doRequest($template,$params,$needMain=false){
        $this->response_data = null;
        $xml = $this->generatorXml($template,$params);
        $retXml = $this->callRemote($xml);
        if($retXml){
            try{
                $xmlObj = new \SimpleXmlIterator($retXml);
                $nameSpaces = $xmlObj->getNamespaces(true);                
                $ret = $this->xmlNameSpaceToArray($xmlObj,$nameSpaces);
                if($ret){
                    $this->response_data = $ret;
                    if($ret['MAIN']['RESULTCODE']=='0000'){
                        if(!$needMain) unset($ret['MAIN']);
                        return $ret;
                    }else{
                        $this->error = $ret['MAIN']['ERR_INFO'];
                    }
                }
            }catch(Exception $e){
                $this->error = $e->getMessage();
            }
        }
        return false;
    }
    
    /**
    * 生成UUID用于交易流水号
    * 
    */
    protected function uuid(){
        $chars = md5(uniqid(mt_rand(), true));  
        return $chars;  
    }
    
    
    /**
    * 查询车辆车型信息
    * 
    */
    public function getVehicleInfo($in_params){
        $base_params = array(
            'business_code' => '13',
            'serialdecimal' => $this->uuid(),
            'transrno' => '1031',
            'transrdate' => date('Y-m-d H:i:s'),
        );
        
        $params = array_merge($base_params,$in_params);
        
        $ret = $this->doRequest('GetCarInfo',$params);
        if($ret){ //只取车辆列表数组
            if(isset($ret['VHLMODEL_LIST']['VHLMODEL'][0])){
                return $ret['VHLMODEL_LIST']['VHLMODEL'];
            }else{
                $retA = array();
                $retA[] = $ret['VHLMODEL_LIST']['VHLMODEL'];
                return $retA;
            }
        }
        return $ret;
    }
    
    
    /**
    * 获取车险承保方案信息
    * 
    */
    public function getScheme($in_params){
        //一律从POST里面取
        $base_params = array(
            'business_code' => '13',
            'serialdecimal' => $this->uuid(),
            'transrno' => '1032',
            'transrdate' => date('Y-m-d H:i:s'),
            't_oper_date' => date('Y-m-d'),
        );
        
        //根据初登日期计算商业险起保日期
        $c_fst_reg_dte = $in_params['c_fst_reg_dte'];
        $now = new \DateTime();
        $dtReg = new \DateTime($c_fst_reg_dte);
        while($dtReg->getTimestamp()<$now->getTimestamp()){
            //如果首登日期大于今天，则直接首登日期否则一年一年累加
            $dtReg = $dtReg->add(new \DateInterval('P1Y'));
        }
        $in_params['t_insrnc_bgn_tm'] = $dtReg->format('Y-m-d 00:00:00');
        
        $params = array_merge($base_params,$in_params);
        
        $ret = $this->doRequest('Scheme',$params);
        if($ret){
            
        }else{
            if($this->response_data && $this->response_data['BASE'] && $this->response_data['BASE']['C_LAST_BUS_END']){
                $dtReg = new \DateTime($this->response_data['BASE']['C_LAST_BUS_END']);
                $dtReg = $dtReg->add(new \DateInterval('P1D'));
                $params['t_insrnc_bgn_tm'] = $dtReg->format('Y-m-d 00:00:00');  //设置商业险起保日期后重新请求
                $ret = $this->doRequest('Scheme',$params);
            }
        }
        return $ret;
    }
    
    /**
    * 保险试算
    * 
    */
    public function calcFee($in_params){
        //一律从POST里面取
        $base_params = array(
            'business_code' => '13',
            'serialdecimal' => $this->uuid(),
            'transrno' => '1033',
            'transrdate' => date('Y-m-d H:i:s'),
            't_oper_date' => date('Y-m-d'),
            't_ys_flag' => 0, //默认掉，统统不约省
        );
        
        $params = array_merge($base_params,$in_params);
        
        Log::record(print_r($params,true),Log::DEBUG);
        
        $ret = $this->doRequest('CalcFee',$params);
        return $ret;
    }
    
    /**
    * 信息校验
    * 
    */
    public function verifyInfo($in_params){
        //一律从POST里面取
        $base_params = array(
            'business_code' => '13',
            'serialdecimal' => $this->uuid(),
            'transrno' => '1036',
            'transrdate' => date('Y-m-d H:i:s'),
            't_oper_date' => date('Y-m-d'),
        );
        
        $params = array_merge($base_params,$in_params);
        
        Log::record(print_r($params,true),Log::DEBUG);
        
        $ret = $this->doRequest('VerifyInfo',$params,true);
        return $ret;
    }
    
    /**
    * 投保确认
    * 
    */
    public function confirm($in_params){
        //一律从POST里面取
        $base_params = array(
            'business_code' => '13',
            'serialdecimal' => $this->uuid(),
            'transrno' => '1037',
            'transrdate' => date('Y-m-d H:i:s'),
            't_oper_date' => date('Y-m-d'),
        );
        
        $params = array_merge($base_params,$in_params);
        
        Log::record(print_r($params,true),Log::DEBUG);
        
        $ret = $this->doRequest('Confirm',$params,true);
        if($ret){
            //保存到数据库中
            $model = M('CicOrder');
            unset($data);
            $data['c_order_no'] = $in_params['c_order_no'];
            $data['serialdecimal'] = $ret['MAIN']['SERIALDECIMAL'];
            $data['transrdate'] = $ret['MAIN']['TRANSRDATE'];
            $data['c_dpt_cde'] = session('c_dpt_cde');
            $data['t_insrnc_bgn_tm'] = $ret['INSURANCE']['T_INSRNC_BGN_TM'];
            $data['t_insrnc_end_tm'] = $ret['INSURANCE']['T_INSRNC_END_TM'];
            $data['t_traff_bgn_tm'] = $ret['INSURANCE']['T_TRAFF_BGN_TM'];
            $data['t_traff_end_tm'] = $ret['INSURANCE']['T_TRAFF_END_TM'];
            $data['n_real_amt'] = $ret['INSURANCE']['N_REAL_AMT'];
            $data['n_prm'] = $ret['INSURANCE']['N_PRM'];
            $data['n_traff_real_prm'] = $ret['INSURANCE']['N_TRAFF_REAL_PRM'];
            $data['n_traff_prm'] = $ret['INSURANCE']['N_TRAFF_PRM'];
            $data['n_tax_real_prm'] = $ret['INSURANCE']['N_TAX_REAL_PRM'];
            $data['n_tax_prm'] = $ret['INSURANCE']['N_TAX_PRM'];
            $data['c_appnt'] = $ret['INSURANCE']['N_TAX_PRM'];
            $data['c_tax_appnt'] = $ret['INSURANCE']['N_TAX_PRM'];
            $data['c_remark'] = $ret['INSURANCE']['C_REMARK'];
            $data['c_app_nme'] = $ret['PARTICIPANT']['C_APP_NME'];
            $data['c_app_sex'] = $ret['PARTICIPANT']['C_APP_SEX'];
            $data['c_app_ident_type'] = $ret['PARTICIPANT']['C_APP_IDENT_TYPE'];
            $data['c_app_ident_no'] = $ret['PARTICIPANT']['C_APP_IDENT_NO'];
            $data['c_app_tel'] = $ret['PARTICIPANT']['C_APP_TEL'];
            $data['c_app_addr'] = $ret['PARTICIPANT']['C_APP_ADDR'];
            $data['c_app_email'] = $ret['PARTICIPANT']['C_APP_EMAIL'];
            $data['c_app_zipcode'] = $ret['PARTICIPANT']['C_APP_ZIPCODE'];
            $data['c_insrnt_nme'] = $ret['PARTICIPANT']['C_INSRNT_NME'];
            $data['c_insrnt_sex'] = $ret['PARTICIPANT']['C_INSRNT_SEX'];
            $data['c_insrnt_ident_type'] = $ret['PARTICIPANT']['C_INSRNT_IDENT_TYPE'];
            $data['c_insrnt_ident_no'] = $ret['PARTICIPANT']['C_INSRNT_IDENT_NO'];
            $data['c_insrnt_tel'] = $ret['PARTICIPANT']['C_INSRNT_TEL'];
            $data['c_insrnt_addr'] = $ret['PARTICIPANT']['C_INSRNT_ADDR'];
            $data['c_insrnt_email'] = $ret['PARTICIPANT']['C_INSRNT_EMAIL'];
            $data['c_insrnt_zipcode'] = $ret['PARTICIPANT']['C_INSRNT_ZIPCODE'];
            $data['c_contact_name'] = $ret['PARTICIPANT']['C_CONTACT_NAME'];
            $data['c_contact_tel'] = $ret['PARTICIPANT']['C_CONTACT_TEL'];
            $data['c_contact_email'] = $ret['PARTICIPANT']['C_APP_NME'];
            $data['c_address'] = $ret['PARTICIPANT']['C_ADDRESS'];
            $data['c_drv_owner'] = $ret['VHL']['C_DRV_OWNER'];
            $data['c_ident_type'] = $ret['VHL']['C_IDENT_TYPE'];
            $data['c_ident_no'] = $ret['VHL']['C_IDENT_NO'];
            $data['c_vehicle_brand'] = $ret['VHL']['C_VEHICLE_BRAND'];
            $data['c_brnd_cde'] = $ret['VHL']['C_BRND_CDE'];
            $data['c_vehicle_name'] = $ret['VHL']['C_VEHICLE_NAME'];
            $data['c_noclm_amt_cde'] = $ret['VHL']['C_NOCLM_AMT_CDE'];
            $data['c_vin_cde'] = $ret['VHL']['C_VIN_CDE'];
            $data['c_lcn_no'] = $ret['VHL']['C_LCN_NO'];
            $data['c_vhl_frm'] = $ret['VHL']['C_VHL_FRM'];
            $data['c_eng_no'] = $ret['VHL']['C_ENG_NO'];
            $data['c_fee_atr'] = $ret['VHL']['C_FEE_ATR'];
            $data['c_fst_reg_dte'] = $ret['VHL']['C_FST_REG_DTE'];
            $data['n_limit_load_person'] = $ret['VHL']['N_LIMIT_LOAD_PERSON'];
            $data['c_whole_weight'] = $ret['VHL']['C_WHOLE_WEIGHT'];
            $data['c_ext_msr'] = $ret['VHL']['C_EXT_MSR'];
            $data['c_power_type'] = $ret['VHL']['C_POWER_TYPE'];
            $data['n_vehicle_price'] = $ret['VHL']['N_VEHICLE_PRICE'];
            $data['c_import_flag'] = $ret['VHL']['C_IMPORT_FLAG'];

            unset($where);
            $where['c_order_no'] = $c_order_no;
            $resCic = $model->where($where)->find();
            if($resCic){
                $orderid = $resCic['corder_id'];
                $model->where($where)->save($data);
            }else{
                $orderid = $model->add($data);
            }
            
            $modelDetail = M('CicOrderDetail');
            $modelDetail->where("corder_id=$orderid")->delete();
            foreach($ret['KIND_LIST']['KIND'] as $kind){
                unset($d);
                $d['corder_id'] = $orderid;
                $d['n_seq_no'] = $kind['N_SEQ_NO'];
                $d['c_kind_cde'] = $kind['C_KIND_CDE'];
                $d['c_kind_name'] = $kind['C_KIND_NAME'];
                $d['n_amt'] = $kind['N_AMT'];
                $d['n_prm'] = $kind['N_PRM'];
                $d['n_seatnum'] = $kind['N_SEATNUM'];
                $modelDetail->add($d);
            }            
        }
        
        return $ret;
    }
    
    /**
    * 申请购买
    * 
    */
    public function buy($in_params){
        //一律从POST里面取
        $base_params = array(
            'business_code' => '13',
            'serialdecimal' => $this->uuid(),
            'transrno' => '1038',
            'transrdate' => date('Y-m-d H:i:s'),
            't_oper_date' => date('Y-m-d'),
        );
        
        $params = array_merge($base_params,$in_params);
        
        Log::record(print_r($params,true),Log::DEBUG);
        
        $ret = $this->doRequest('Buy',$params);
        if($ret){
            //记录投保保单号
            $modelCic = M('CicOrder');
            $modelDh = M('CicOrderDh');
            unset($where);
            $where['c_order_no'] = $in_params['c_order_no'];
            $resCic = $modelCic->where($where)->find();
            if($resCic){
                foreach($ret['POLICY_LIST']['POLICY'] as $policy){
                    unset($data);
                    $data['corder_id'] = $resCic['corder_id'];
                    $data['c_proposal_no'] = $policy['C_PROPOSAL_NO'];
                    $data['business_code'] = $policy['BUSINESS_CODE'];
                    $modelDh->add($data);
                }
            }
        }
        return $ret;
    }
}
